1. Field of the Invention
The invention relates to a firmware structuring method and related apparatus, and more particularly, to a method and apparatus which uses level management and unifies handling error recovery to eliminate the complexity of firmware.
2. Description of the Prior Art
In modern information society, information, images, and data are transferred, stored, and processed digitally and various electronic systems and devices, from mobile phones to computers used for accessing digital signals, have become essential appliances. In general, most electronic devices have a processor (or a microprocessor) for controlling operations. In the case of multi-functional or complex devices, the processor needs program code to specify related steps and control procedures due to the control procedures being more complex. The processor executes this program code to implement different functions of the electronic device. This program code is referred to as firmware code and is often stored in a non-volatile memory (flash memory for example) in order that the processor can read and execute it more efficiently. Additionally, in more complex electronic systems such as computers, peripheral devices have their own processor and corresponding firmware code. The host only needs to send higher-level control commands to the peripheral processor, which executes its own firmware code to control operations of the peripheral device. For instance, an optical disk drive of computer system has a processor and corresponding flash memory to store the firmware code. When the host wants to retrieve data stored on an optical disk, it just need to indicate the data address to optical disk drive and the processor of the optical disk drive executes its own firmware code to coordinate the operations of the spindle, pick-up head, and other components (such as requiring the spindle to reach a specific rotation speed and requiring the pick-up head to execute track seeking and track locking to a specific position to receive the reflection laser from the optical disk).
Please refer to FIG. 1. FIG. 1 is a function block diagram of a typical peripheral device 12 connected with a host 10. The peripheral device 12 is a typical electronic device having a processor 16 for controlling operations. Additionally, the peripheral device 12 further includes a volatile buffer memory 22 (like a random access memory), a non-volatile memory 24 (like a flash memory), and a hardware circuit 18 for implementing the functions of the peripheral device 12. The peripheral device 12 is usually connected to the host 10 and operates according to the control commands received from the host 10. The host 10 can be a computer having a CPU (central processing unit) 14A, a north bridge circuit 14B, a south bridge circuit 14C, a graphics card 14E, a monitor 14F, and a volatile memory 14D (like arandom access memory, RAM). The CPU 14A is used for controlling the operations of the host 10, the memory 14D is used for temporarily storing required data and programs of the CPU 14A, the graphics card 14E is used for processing image signals to transform the operational situation of the host 10 into an image on the monitor 14F. The north bridge circuit 14B is used for controlling the data transfer between the graphics card 14E, the memory 14D, and the CPU 14A; the south bridge circuit 14C is electrically connected to the CPU 14A via the north bridge circuit 14B, the peripheral device 12 exchanges instructions and data with the host 10 via the connection (such as via an IDE bus) with the south bridge circuit 14C.
In the peripheral device 12, in addition to the processor 16, a buffer memory 22 is used for temporarily storing required data during the peripheral device 12 operations, and a hardware circuit 18 having a codec 20A, a DSP (digital signal processor) 20B, and a servo module 20C is included. Since the instructions and data transfer between the host 10 and the peripheral device 12 must comply with a regular form or protocol, the codec 20A decodes the instructions and data transferred from the host 10 to the peripheral device 12. The processor 16 then controls the peripheral device 12 according to the decoded instructions and signals. In other words, the data transferred from the peripheral device 12 to the host 10 is also properly encoded by the codec 20A to comply with the data exchange format and protocol. The servo module 20C is controlled by the processor 16 to implement the main function of the peripheral device 12 and the DSP 20B processes the data and signals accessed by the servo module 20C. For example, if the peripheral device 12 were an optical disk drive used for accessing the data of an optical disk, servo module 20C would have a spindle 28A, a pick-up head 28B, and other required electrical components. The spindle 28A is used for rotating an optical disk 28C; the pick-up head 28B slides along a sliding track 28D to access data on different tracks of the optical disk. The data retrieved from the optical disk 28C by the servo module 20C is then processed by the DSP 20B and stored in the buffer memory 22 according to the arrangement of the processor 16, so that the host 10 can access data in the buffer memory 22 via the codec 20A. The host 10 retrieves data from the optical disk 28C via the peripheral device 12 of the optical disk drive. In other words, if the host 10 wants to write data to the optical disk 28C, it will transfer data to the buffer memory 22 via the codec 20A and under control of the processor 16, the host 10 then uses the servo module 20C to write the data temporarily stored in the buffer memory 22 to the optical disk 28C.
As mentioned above, the processor 16 of the peripheral device 12 controls the operations of the peripheral device 12 according to the control procedure recorded in the programs and the firmware code 26 stored in the non-volatile memory 24 used for recording these control procedures. The processor 16 executes the firmware code 26 to control the peripheral device 12 to execute various operations.
Please refer to FIG. 2, as well as to FIG. 1. FIG. 2 is a flowchart diagram of typical program structure of the firmware code 26 of the prior art. The firmware code 26 can be divided into two groups, one is an interface program IF0 and the other is a servo program SR0. The servo program SR0 includes a plurality of subroutines (such as subroutines R1, R2A-R2B, R3A-R3B, R4A-R4B, R5A-R5B, R6A-R6B, and R7A-R7B shown in FIG. 2 for example), wherein each subroutine is used for controlling the hardware circuit 18 to execute some specific operations. For example, a subroutine could control the pick-up head 28B of the servo module 20C to move from a position to another along the sliding track 28D, another subroutine could control the pick-up head 28B to adjust the power of a laser, and so on. The interface program IF0 also includes a plurality of subroutines, the main function of the interface program IF0 calls the corresponding subroutine of the servo program SR0 according to the instructions of the host 10 allowing the hardware circuit 18 to implement the function assigned by the host 10. An execution result of the servo program SR0 will return to the host 10 after executing the interface program IF0. For example, if the host 10 requests the peripheral device 12 to retrieve some data from an optical disk, the interface program IF0 calls the subroutine having the definition of data retrieving procedure of the servo program SR0. The processor 16 then executes this subroutine to control the hardware circuit 18 to implement this data retrieving procedure. If the subroutine completes successfully, it will send a procedure-finished message (such a message could be stored in a variable). The interface program IF0, according to this message, controls the peripheral device 12 to respond with the proper signals to the host 10 to indicate the result of procedure.
In general, owing to the rapid development of electronic devices, device controlling procedures and firmware code are becoming more and more complex. In order to shorten developing time, there are often many firmware engineers cooperating to each write a part of the subroutines and then integrate each part into the firmware code. As is well known in the art, a subroutine can modularize specific control procedures for convenient reuse. For example, in an optical disk drive, the pick-up head 28B is controlled to move from a position to another along the sliding track 28D when initialized after boot and when retrieving specific data from an optical disk or writing data to an optical disk. The program controlling the movement of the pick-up head 28B can be modularized into a subroutine and the programs used for controlling the optical disk drive to execute booting initialization, data retrieving or data writing, could call this subroutine to control the movement of the pick-up head to implement the action. Thereby, the engineers who are developing different subroutines do not unnecessary repeat coding the programs which are used for controlling the movement of the pickup head in the booting initializations, data retrieving and data writing programs.
Although sharing the same subroutines in different control procedures is convenient for developing firmware code, the prior art lacks the management for controlling the calls between subroutines. In particular, when each subroutine is developed by different firmware engineers, the engineer who developed a subroutine A may call a subroutine B, which engineer B developed, and the engineer who developed the subroutine A may not understand the detail of the subroutine B. Subroutine B may need to invoke a subroutine C, and the subroutine C need to further invoke a subroutine D, and so on. In this way, the operational flow of the invoked subroutines becomes too complex to control. Please refer to FIG. 2 illustrating a complex operational flow. The arrowheads shown in FIG. 2 represent the flow between subroutines. For instance, the processor 16 needs to execute a subroutine R1 of the servo program SR0 according to the call of the interface program IF0. The arrowhead A1 indicates that the subroutine R1 is executed. The subroutine R1 invokes the subroutines R2A and R2B in sequence and the arrowhead A2 indicates that the subroutine R2A is executed. After the subroutine R2A finishes, the arrowhead A3 indicates that subroutine R2B is executed. The subroutine R2B further invokes the subroutines R3A and R3B. The arrowhead A4 indicates the subroutine R3A is executed and the arrowhead A5 indicates that the subroutine R3B is next executed. The subroutine R3B further invokes the subroutines R4A and R4B in sequence, and the arrowhead A6 indicates that the subroutine R4A is executed. The arrowhead A7 indicates that subroutine R4B is executed. The subroutine R4B further invokes the subroutines R5A, R5B, and R5C in sequence, as indicated by the arrowheads A8, A9 and A10 respectively. When executing the subroutine R5C, the subroutines R6A and R6B are invoked. The arrowhead A11 indicates that subroutine R6A is executed and the subroutine R6A further invokes the subroutines R7A and R7B in sequence. The program next executes the subroutines R7A and R7B in sequence as shown by the arrowheads A12 and A13 respectively. The subroutine R6A is executed as indicated by the arrowhead A14. When the subroutine R6A is finished, the program continues and executes the subroutine R6B as the arrowhead A15 indicates. When the two subroutines R6A and R6B invoked by the subroutine R5C both finish, the program continues and executes the subroutine R5C as the arrowhead A16 indicates. The program proceeds with the subroutine R4B as indicated by the arrowhead A17. When the subroutine R5C finishes, the rest of the control procedure for the subroutines R5A to R5C is executed and then the subroutine R4B executes. When the subroutine R4B finishes, the program proceeds with the subroutine R3B as the arrowhead A18 indicates. When the subroutine R3B is finished, the subroutine R2B, which invoked subroutines R3A and R3B is executed as the arrowhead A19 indicates. When the subroutine R2B is finished, the execution flow will proceed to execute the subroutine R1 as the arrowhead A20 indicates. When the subroutine R1 is finished, the result of the execution of the subroutine R1 is returned to the interface program IF0 as the arrowhead A21 indicates.
As mentioned above, if subroutines are invoked without proper management, the execution flow may become too complex to trace. For example, while the firmware engineer develops the subroutine R1, the firmware engineer may invoke the subroutine R2B in the subroutine R1 due to the function of the subroutine R2B matching a required step of the controlling procedure. However, the firmware engineer may ignore that the subroutine R2B invokes subroutines R3A and R3B in sequence and the subroutine R3B will further invoke others. In this way, by executing the subroutine R1, the developing firmware engineer can not control the actual operational flow. If the developing firmware engineer needs to trace the execution flow of the subroutine R2A, it is no longer convenient to modularize the program code with subroutines.
Additionally, the complex and lengthy execution flow will consume considerable resources of the processor of the peripheral device 12. For instance, as is well known in the art, while the subroutine R1 is executed, if a program wants to execute the subroutine R2A invoked by the subroutine R1, as the arrowhead A2 indicates, each variable value of the subroutine R1 is temporarily stored in a stack arranged in the buffer memory 22 and can not be released. Further, while executing the subroutine R2B, subroutines R3A and R3B are invoked and each variable value of the subroutine R2B is temporarily stored in the stack and can not be released either. To continue executing the subroutines R3A and R3B, each variable value of the subroutine R3B is temporarily stored in the stack and can not be released before invoking subroutines R4A and R4B. In other words, in follow-up execution flow, each variable value of a subroutine A should be temporarily stored in the stack and can not be released before the subroutine B invoked by the subroutine A is finished. It is obvious that the more subroutines invoked during the execution flow (caused by some subroutines executing other subroutines once executed), the more variable values in the stack and the more memory space required of the buffer memory 22.
In addition, the complex and long series of different subroutine executions will make the program become more difficult to debug. Once a bug occurs, the firmware engineer must check each subroutine of the execution flow to find the crux of the problem. Additionally, when the need arises to debug a specific subroutine, difficulty is encountered since the firmware engineer can not be aware of the execution situation about the flow of subroutines. For example, when the firmware engineer checks the subroutine R4B, it is difficult to determine whether the operation of the subroutine R4B is correct since the execution situation of the other subroutines R3A, R3B and R5A to R5C in not known. If the subroutine R4B has a bug, it may cause an error of the subroutine R3A or the subroutines R5A to R5C.
Except the drawbacks mentioned above, nested execution of subroutines also causes difficult error recovery operations of the peripheral device 12. The firmware code 26 of the peripheral device 12 is used for integrating the operations of each electric component of the peripheral device 12. If there is a component malfunction (or a user suddenly changes the control of the peripheral device), it would interrupt normal execution flow of the firmware code 26 and cause an operation error of the peripheral device 12. At this time, the program runs an error recovery operation to recover the operation of the peripheral device 12 from abnormal malfunction. For example, if an optical disk drive is shocked suddenly during data retrieval and the position of the pick-up head 28B is changed, the optical disk drive probably needs to execute a track locking or a track seeking operation to recover to a normal data retrieving state. Of course the control procedure of the error recovery should be included in the firmware code 26 to control the peripheral device 12 for executing a recover operation when an error occurs. Please refer to FIG. 3. FIG. 3 is a schematic diagram of a typical program structure of the firmware code 26 of the prior art and is similar to FIG. 2. FIG. 3 further shows the practical method of error recovery of the prior art. As shown in FIG. 3, when the processor 16 executes the subroutine R3B to control the peripheral device 12 to operate, if an error occurs in the operations of the peripheral device 12, subroutines R8A and R8B are executed under the logic control of the step R3s for controlling the peripheral device 12 to execute the error recovery operations. When the subroutines R8A and R8B have finished correctly, the execution flow of the subroutine R1 proceeds to the subroutine R2B as the arrowhead A19 indicates.
However, in the prior art, incorrect error recovery commonly occurs in complex execution flows of series executions due to lack of management for error recovery. For example, as shown in FIG. 3, the subroutine R5A includes an error recovery mechanism. If an operational error of the peripheral device 12 occurs during execution of the subroutine R5A, the subroutine R9 is executed under the logic control of the step R5s to carry out error recovery. However, the firmware engineer who developed the subroutine R3B probably ignored the subroutine R5A, invoked by the subroutine R4B, and which already includes an error recovery mechanism, so that the controlling procedure related to the subroutine R5A error recovery is duplicated within subroutines R8A and R8B which account for the subroutine R3B recovery mechanism. The duplicated error recovery probably causes an execution flow delay, and could even cause an additional operational error of the peripheral device 12. Similarly, due to the firmware engineer who developed the subroutine R3B not being aware that the subroutine R4B will invoke the subroutine R6A, the recovery operations corresponding to the subroutine R6A error operation would not be included in the error recovery subroutines R8A and R8B. Once an operation error occurs in the peripheral device 12, while executing the subroutine R6A, the peripheral device 12 can not execute correct error recovery. In other words, in the prior art, due to the lack of management for error recovery in the execution flow of nested executions, an additional operational error is probably caused without properly error recovery, or too many redundant error recoveries are invoked without any error management.
In summary, because there is a lack of effective management for invoked subroutines and error recovery in the prior art, the firmware code structure is lower readability and too complex to trace and to debug, will consume considerable resources of the processor of the peripheral device, and will easily affect the normal operations of the peripheral device due to the lack of management for error recovery.